/**
 * 测试赤壁开奖结果保存脚本
 * 通过WebSocket查询验证修复后的开奖逻辑是否正确保存 winningSide、battleReport 等到数据库
 */

const http = require('http');
const WebSocket = require('ws');

// 测试配置
const CONFIG = {
    server: {
        host: 'localhost',
        port: 3000,
        protocol: 'http'
    },

    // 测试用户信息
    testUser: {
        mobile: '17091271111',
        password: '123456',
        passwordHash: 'e10adc3949ba59abbe56e057f20f883e' // 123456的SHA256
    }
};

class CasinoChibiResultTester {
    constructor() {
        this.token = null;
        this.userId = null;
        this.ws = null;
        this.testResults = [];
        this.messageId = 1; // 消息ID计数器
    }

    // 运行完整测试流程
    async runTest() {
        console.log('🏰 开始测试赤壁开奖结果保存逻辑...\n');
        console.log('测试目标：通过WebSocket验证开奖后的 winningSide、battleReport 等是否正确保存到数据库\n');

        try {
            // 1. HTTP登录
            await this.testHttpLogin();

            // 2. 建立WebSocket连接
            await this.testWebSocketConnection();

            // 3. 通过WebSocket查询当前期数信息
            await this.testQueryCurrentRoundViaWS();

            // 4. 等待期数结束并开奖
            await this.testWaitForSettlement();

            // 5. 通过WebSocket验证开奖结果是否保存到数据库
            await this.testVerifyResultViaWS();

            // 6. 断开连接
            await this.testDisconnect();

            // 输出测试结果
            this.printTestResults();

        } catch (error) {
            console.error('❌ 测试过程中发生错误:', error.message);
            this.addTestResult('整体测试', false, error.message);
        }
    }

    // 1. HTTP登录测试
    async testHttpLogin() {
        console.log('🔐 步骤1: HTTP登录测试...');

        try {
            // 执行登录
            const loginData = await this.makeHttpRequest('/user-service/user/login', 'POST', {
                mobile: CONFIG.testUser.mobile,
                pwd: CONFIG.testUser.passwordHash
            });

            if (loginData.code === 0 && loginData.data) {
                this.userId = loginData.data.userId;
                this.token = loginData.data.accessToken;

                console.log(`✅ 登录成功: userId=${this.userId}, token=${this.token.substring(0, 8)}...`);
                this.addTestResult('HTTP登录', true, `用户ID: ${this.userId}`);
            } else {
                throw new Error(`登录失败: ${loginData.msg || '未知错误'}`);
            }

        } catch (error) {
            console.log('❌ 登录失败:', error.message);
            this.addTestResult('HTTP登录', false, error.message);
            throw error;
        }
    }

    // 2. WebSocket连接测试
    async testWebSocketConnection() {
        console.log('\n🔌 步骤2: WebSocket连接测试...');

        return new Promise((resolve, reject) => {
            try {
                const wsUrl = `ws://${CONFIG.server.host}:${CONFIG.server.port}/user-service/websocket?t=${this.token}`;
                this.ws = new WebSocket(wsUrl);

                this.ws.on('open', async () => {
                    console.log('✅ WebSocket连接成功');
                    this.addTestResult('WebSocket连接', true, '连接建立成功');

                    // 等待连接完全稳定
                    await this.delay(500);
                    resolve();
                });

                this.ws.on('error', (error) => {
                    console.log('❌ WebSocket连接失败:', error.message);
                    this.addTestResult('WebSocket连接', false, error.message);
                    reject(error);
                });

                this.ws.on('close', () => {
                    console.log('🔌 WebSocket连接已关闭');
                });

                // 连接超时
                setTimeout(() => {
                    if (this.ws.readyState === WebSocket.CONNECTING) {
                        this.ws.close();
                        reject(new Error('连接超时'));
                    }
                }, 10000);

            } catch (error) {
                reject(error);
            }
        });
    }

    // 3. 通过WebSocket查询当前期数信息
    async testQueryCurrentRoundViaWS() {
        console.log('\n📊 步骤3: 通过WebSocket查询当前期数信息...');

        try {
            // 使用act_id 4430查询赤壁玩法信息
            const response = await this.sendWebSocketMessage(4430, {});

            if (response.code === 0 && response.data) {
                const roundData = response.data;
                console.log(`✅ 通过WebSocket获取当前期数成功: 期数ID=${roundData.curRndNum}`);
                console.log(`   剩余时间: ${roundData.second}秒`);
                console.log(`   上期获胜方: ${this.getSideName(roundData.preSide)}`);

                this.addTestResult('WebSocket查询当前期数', true, `期数ID: ${roundData.curRndNum}, 剩余时间: ${roundData.second}秒`);

                // 计算需要等待的时间
                const waitTime = Math.max(0, roundData.second) + 5; // 多等5秒确保开奖完成
                console.log(`⏰ 需要等待 ${waitTime} 秒让期数结束并开奖...`);

                return waitTime;
            } else {
                throw new Error(`WebSocket查询期数失败: ${response.msg || '未知错误'}`);
            }
        } catch (error) {
            console.log('❌ WebSocket查询期数失败:', error.message);
            this.addTestResult('WebSocket查询当前期数', false, error.message);
            throw error;
        }
    }

    // 4. 等待期数结束并开奖
    async testWaitForSettlement(waitTime) {
        console.log('\n⏳ 步骤4: 等待期数结束并开奖...');

        return new Promise((resolve) => {
            console.log(`⏰ 等待 ${waitTime} 秒...`);

            setTimeout(async () => {
                console.log('✅ 等待完成，期数应该已经开奖');
                this.addTestResult('等待开奖', true, `等待${waitTime}秒完成`);
                resolve();
            }, waitTime * 1000);
        });
    }

    // 5. 通过WebSocket验证开奖结果是否保存到数据库
    async testVerifyResultViaWS() {
        console.log('\n🔍 步骤5: 通过WebSocket验证开奖结果是否保存到数据库...');

        try {
            // 使用act_id 4434查询赤壁玩法历史记录（包含开奖结果）
            const response = await this.sendWebSocketMessage(4434, { pageNum: 0 });

            if (response.code === 0 && response.data) {
                const historyData = response.data;
                console.log(`✅ 通过WebSocket获取历史记录成功: 总期数=${historyData.total}`);

                if (historyData.rounds && historyData.rounds.length > 0) {
                    // 获取最新一期（应该是刚开奖的期数）
                    const latestRound = historyData.rounds[0];
                    console.log(`📊 最新期数: ID=${latestRound.id}, 状态=${latestRound.status}`);

                    // 检查开奖结果字段
                    const resultFields = ['winningSide', 'battleReport', 'reportStr'];
                    const missingFields = [];
                    const validFields = [];

                    resultFields.forEach(field => {
                        if (latestRound[field] === null || latestRound[field] === undefined) {
                            missingFields.push(field);
                        } else {
                            validFields.push(`${field}=${latestRound[field]}`);
                        }
                    });

                    if (missingFields.length === 0) {
                        console.log('✅ 所有开奖结果字段都已正确保存:');
                        validFields.forEach(field => console.log(`   ${field}`));
                        this.addTestResult('WebSocket验证开奖结果', true, `所有字段已保存: ${validFields.join(', ')}`);
                    } else {
                        console.log('❌ 以下开奖结果字段缺失或为空:');
                        missingFields.forEach(field => console.log(`   ${field}: null/undefined`));
                        this.addTestResult('WebSocket验证开奖结果', false, `缺失字段: ${missingFields.join(', ')}`);
                    }

                    // 特别检查获胜方
                    if (latestRound.winningSide) {
                        const sideNames = { 1: '魏国', 2: '蜀国', 3: '吴国' };
                        console.log(`🏆 获胜方: ${sideNames[latestRound.winningSide] || '未知'} (${latestRound.winningSide})`);

                        if (latestRound.battleReport) {
                            console.log(`📜 战斗报告: ${latestRound.battleReport}`);
                        }

                        if (latestRound.reportStr) {
                            console.log(`📝 报告字符串: ${latestRound.reportStr}`);
                        }
                    } else {
                        console.log('❌ 获胜方字段缺失或为空');
                    }

                    // 检查期数状态
                    if (latestRound.status === 2) { // 假设2表示已结算状态
                        console.log('✅ 期数状态正确：已结算');
                    } else {
                        console.log(`⚠️ 期数状态: ${latestRound.status} (期望为已结算状态)`);
                    }

                } else {
                    console.log('❌ 历史记录为空，无法验证开奖结果');
                    this.addTestResult('WebSocket验证开奖结果', false, '历史记录为空');
                }

            } else {
                throw new Error(`WebSocket查询历史记录失败: ${response.msg || '未知错误'}`);
            }
        } catch (error) {
            console.log('❌ WebSocket验证开奖结果失败:', error.message);
            this.addTestResult('WebSocket验证开奖结果', false, error.message);
        }
    }

    // 6. 断开连接
    async testDisconnect() {
        console.log('\n🔌 步骤6: 断开WebSocket连接...');
        if (this.ws) {
            this.ws.close();
        }
        this.addTestResult('断开连接', true, '连接已断开');
    }

    // 发送WebSocket消息并等待响应
    async sendWebSocketMessage(actId, data) {
        return new Promise((resolve, reject) => {
            const messageId = this.messageId++;
            const message = {
                act_id: actId,
                data: data,
                msg_id: messageId
            };

            // 设置响应处理器
            const responseHandler = (response) => {
                if (response.act_id === actId) {
                    this.ws.removeEventListener('message', responseHandler);
                    resolve(response);
                }
            };

            this.ws.addEventListener('message', responseHandler);

            // 发送消息
            this.ws.send(JSON.stringify(message));

            // 设置超时
            setTimeout(() => {
                this.ws.removeEventListener('message', responseHandler);
                reject(new Error(`WebSocket消息超时: act_id=${actId}`));
            }, 10000);
        });
    }

    // 获取国家名称
    getSideName(side) {
        const sideNames = { 1: '魏国', 2: '蜀国', 3: '吴国', 0: '无' };
        return sideNames[side] || '未知';
    }

    // 添加测试结果
    addTestResult(testName, success, message) {
        this.testResults.push({
            test: testName,
            success: success,
            message: message,
            timestamp: new Date().toISOString()
        });
    }

    // 打印测试结果
    printTestResults() {
        console.log('\n📊 测试结果汇总:');
        console.log('='.repeat(50));

        let successCount = 0;
        let totalCount = this.testResults.length;

        this.testResults.forEach((result, index) => {
            const status = result.success ? '✅' : '❌';
            console.log(`${index + 1}. ${status} ${result.test}: ${result.message}`);
            if (result.success) successCount++;
        });

        console.log('='.repeat(50));
        console.log(`总计: ${successCount}/${totalCount} 项测试通过`);

        if (successCount === totalCount) {
            console.log('🎉 所有测试通过！赤壁开奖结果保存逻辑修复成功！');
        } else {
            console.log('⚠️  部分测试失败，请检查日志');
        }
    }

    // HTTP请求工具方法
    async makeHttpRequest(path, method = 'GET', data = null) {
        return new Promise((resolve, reject) => {
            const options = {
                hostname: CONFIG.server.host,
                port: CONFIG.server.port,
                path: path,
                method: method,
                headers: {
                    'Content-Type': 'application/json',
                }
            };

            if (data) {
                const postData = JSON.stringify(data);
                options.headers['Content-Length'] = Buffer.byteLength(postData);
            }

            const req = http.request(options, (res) => {
                let body = '';

                res.on('data', (chunk) => {
                    body += chunk;
                });

                res.on('end', () => {
                    try {
                        const responseData = JSON.parse(body);
                        if (res.statusCode >= 200 && res.statusCode < 300) {
                            resolve(responseData);
                        } else {
                            reject(new Error(`HTTP ${res.statusCode}: ${responseData.message || body}`));
                        }
                    } catch (error) {
                        if (res.statusCode >= 200 && res.statusCode < 300) {
                            resolve(body);
                        } else {
                            reject(new Error(`HTTP ${res.statusCode}: ${body}`));
                        }
                    }
                });
            });

            req.on('error', (error) => {
                reject(error);
            });

            if (data) {
                req.write(JSON.stringify(data));
            }

            req.end();
        });
    }

    // 延迟函数
    async delay(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
}

// 运行测试
async function main() {
    const tester = new CasinoChibiResultTester();
    await tester.runTest();
}

// 如果直接运行此脚本
if (require.main === module) {
    main().catch((error) => {
        console.error('💥 测试脚本执行失败:', error.message);
        process.exit(1);
    });
}

module.exports = CasinoChibiResultTester; 